home *** CD-ROM | disk | FTP | other *** search
- /*
- * mpage.c
- */
-
- /*
- * mpage: a program to reduce pages of print so that several pages
- * of output appear on one printed page.
- *
- * Copyright (c) 1988 Mark P. Hahn, Herndon, Virginia
- * Copyright (c) 1994-1997 Marcel J.E. Mol, The Netherlands
- * marcel@mesa.nl
-
- * Written by:
- * ...!uunet!\ Mark Hahn, Sr Systems Engineer
- * >pyrdc!mark Pyramid Technology Corporation
- * ...!pyramid!/ Vienna, Va (703)848-2050
- *
- *
- * Permission is granted to anyone to make or distribute verbatim
- * copies of this document as received, in any medium, provided
- * that this copyright notice is preserved, and that the
- * distributor grants the recipient permission for further
- * redistribution as permitted by this notice.
- *
- */
-
- #include "mpage.h"
- #include <string.h>
- #include <time.h>
- #include <fcntl.h>
-
- #include "encoding.h"
-
- /*
- * Function Declarations
- */
- static void ps_title();
-
-
-
- int
- main(argc, argv)
- int argc;
- char **argv;
- {
- FILE *outfd;
- int currarg;
- struct sheet *thelist;
- struct sheet *thesheet;
- char outcommand[LINESIZE]; /* the command which is the output filter */
-
-
- #ifdef OS2
- /*
- * wildcard expansion from emx package
- */
- _wildcard (&argc, &argv);
- #endif
-
- /*
- * examine the environment for PRINTER (or LPDEST) and MPAGE
- * environment variables
- */
- if ((currarg = do_env()) < 0) {
- usage(currarg);
- exit(1);
- }
-
- if ((currarg = do_args(argc, argv, 0)) < 0) {
- usage(currarg);
- exit(1);
- }
-
- /*
- * if a print queue was specified then create a print command using
- * the queue, else use standard output.
- */
- if (doprint) {
- if (printque != NULL)
- (void) sprintf(outcommand, "%s %s%s",
- printprog, printarg, printque);
- else
- (void) strcpy(outcommand, printprog);
- if ((outfd = popen(outcommand, "w")) == NULL) {
- fprintf(stderr, "%s: cannot create pipe for '%s'\n",
- MPAGE, outcommand);
- perror(MPAGE);
- }
- }
- else
- outfd = stdout;
-
- /*
- * pick the array of sheet lists based upon the specified option
- */
- if (sheetorder == UPDOWN)
- sheetlist = up_down;
- else
- sheetlist = left_right;
-
- /*
- * from the array of sheet lists pick the proper sheet list for
- * the given sheetaspect, then select the proper sheet format
- * for the given number of redueced pages per output page
- */
- thelist = sheetlist[sheetaspect];
- thesheet = &(thelist[sheetindex]);
-
- /* GPN. */
- if (Coli == 1)
- thesheet = &(coli[0]);
- if (Coli == 2)
- thesheet = &(coli[1]);
-
- orientation = (sheetindex + sheetaspect) & 0x01;
-
- /*
- * if either lines or columns were specified as options, over
- * the default sheets idea of the number of line or columns
- * per reduced page
- */
- if (opt_lines > 0)
- thesheet->sh_plength = opt_lines;
- if (opt_width > 0)
- thesheet->sh_cwidth = opt_width;
-
- /*
- * Prepare the textbox parameters when needed
- */
- if (opt_textbox) {
- textbox.over = textmargin_left;
- textbox.lift = textmargin_bottom;
- textbox.wide = thesheet->sh_cwidth - (textmargin_left+textmargin_right);
- textbox.high = thesheet->sh_plength - (textmargin_top+textmargin_bottom);
- }
-
- /*
- * if there are arguments left over after processing options, then
- * these are names of files to process, else process the standard
- * input
- */
- if (currarg < argc) {
- ps_title(argv[currarg], outfd);
- for ( ; currarg < argc; currarg++)
- do_file(argv[currarg], thesheet, outfd);
- }
- else {
- ps_title("<stdin>", outfd);
- do_stdin(thesheet, outfd);
- }
-
- /*
- * in case files are merged on sheets, make sure the last page
- * is printed...
- */
- if (points->pp_origin_x != 0 && !opt_file) {
- if (had_ps)
- fprintf(outfd, "showsheet\n");
- else {
- fprintf(outfd, "restore\n");
- fprintf(outfd, "showpage\n");
- }
- }
-
- /*
- * having processed all input, print out a PS trailer
- * (timing stuff stolen from old adobe troff stuff)
- */
- fprintf(outfd, "%%%%Trailer\n");
- if (opt_verbose) {
- /*
- ps_pagenum++;
- fprintf(outfd, "%%%%Page: %d %d\n", ps_pagenum, ps_pagenum);
- */
- fprintf(outfd, "statusdict begin jobname print flush");
- fprintf(outfd, " (: Job finished:\\n) print\n");
- fprintf(outfd, "(\\tmpage time (s) = ) print flush usertime ");
- fprintf(outfd, "mp_stm sub 1000 div ==\n(\\tmpage pages = ) print");
- fprintf(outfd, " flush pagecount mp_pgc sub ==\nend flush\n");
- /* fprintf(outfd, "showpage\n"); */
- }
- fprintf(outfd, "%%%%Pages: %d\n", ps_pagenum);
- if (opt_verbose) {
- fprintf(stderr, "[%s: %d pages, ", MPAGE, ps_pagenum);
- if (doprint) {
- if (printque != NULL)
- fprintf(stderr, "print queue %s]\n", printque);
- else
- fprintf(stderr, "on default printer queue]\n");
- }
- else
- fprintf(stderr, "on <stdout>]\n");
- }
- /*
- * proper clean up to make sure the pipe is flushed
- */
- if (doprint)
- (void) pclose(outfd);
-
- return 0;
-
- } /* main */
-
-
-
- /*
- * ps_title prints a post script header suitable for PS processors
- */
- static void
- ps_title(name, outfd)
- char *name;
- FILE *outfd;
- {
- time_t curr_time;
- char *time_str;
- FILE * charfp;
- char buf[LINESIZE];
-
- fprintf(outfd, "%%!PS-Adobe-2.0\n");
- fprintf(outfd, "%%%%DocumentFonts: %s Times-Bold\n", fontname);
- fprintf(outfd, "%%%%Title: %s (%s)\n", name, MPAGE);
- fprintf(outfd, "%%%%Creator: %s %s\n", MPAGE, VERSION);
- (void) time(&curr_time);
- time_str = ctime(&curr_time);
- fprintf(outfd, "%%%%CreationDate: %s", time_str);
- fprintf(outfd, "%%%%Orientation: %s\n", orientation ? "Landscape" : "Portrait");
- fprintf(outfd, "%%%%DocumentMedia: %s %d %d\n", media, ps_width, ps_height);
- fprintf(outfd, "%%%%BoundingBox: %d %d %d %d\n",
- sheetmargin_left, sheetmargin_bottom,
- ps_width - sheetmargin_right,
- ps_height - sheetmargin_top);
- fprintf(outfd, "%%%%Pages: (atend)\n");
- fprintf(outfd, "%%%%EndComments\n\n");
- fprintf(outfd, "%%%%BeginProlog\n\n");
- fprintf(outfd, "/mp_stm usertime def\n");
- fprintf(outfd, "/mp_pgc statusdict begin pagecount end def\n");
- fprintf(outfd, "statusdict begin /jobname (%s) def end\n", name);
- if (opt_duplex) {
- fprintf(outfd, "statusdict /setduplexmode known");
- fprintf(outfd, " { statusdict begin true setduplexmode end } if\n");
- if (opt_tumble) {
- fprintf(outfd, "statusdict /settumble known ");
- fprintf(outfd, "{ statusdict begin true settumble end } if\n");
- }
- }
- if (opt_encoding) {
- fprintf(outfd,
- "/reencsmalldict 12 dict def "
- "/ReEncodeSmall { reencsmalldict begin\n"
- "/newcodesandnames exch def "
- "/newfontname exch def "
- "/basefontname exch def\n"
- "/basefontdict basefontname findfont def "
- "/newfont basefontdict maxlength dict def\n"
- "basefontdict "
- "{ exch dup /FID ne "
- "{ dup /Encoding eq "
- "{ exch dup length array copy newfont 3 1 roll put } "
- "{ exch newfont 3 1 roll put }\n"
- "ifelse }\n"
- " { pop pop }\n"
- " ifelse } "
- "forall\n"
- "newfont /FontName newfontname put\n"
- "newcodesandnames aload pop "
- "newcodesandnames length 2 idiv\n"
- "{ newfont /Encoding get 3 1 roll put } "
- "repeat\n"
- "newfontname newfont definefont pop "
- "end } def\n");
-
- fprintf(outfd, "/charvec [\n");
-
- if (charvec_file != NULL) {
- if ((charfp = fopen(charvec_file, "r")) == NULL) {
- perror(charvec_file);
- exit(1);
- }
- while (fgets(buf, LINESIZE, charfp) != NULL) {
- if (*buf != '%' && *buf != '\n')
- if (first_encoding == -1) {
- first_encoding = atoi(buf);
- last_encoding = atoi(strchr(buf, ' '));
- # ifdef DEBUG
- fprintf(stderr, "first=%d, last=%d\n",
- first_encoding, last_encoding);
- #endif
- }
- else
- fprintf(outfd, "%s", buf);
- }
- }
- else { /* use internal default encoding */
- int i;
-
- first_encoding = encoding_table_first;
- last_encoding = encoding_table_last;
- for (i = 0; i <= last_encoding - first_encoding; i++)
- fprintf(outfd, "%s\n", encoding_table[i]);
- }
- fprintf(outfd, "] def\n");
- fprintf(outfd, "/%s /OurCharSet charvec ReEncodeSmall\n", fontname);
- }
- else {
- first_encoding = ' ';
- last_encoding = '~';
- }
-
- fprintf(outfd, "/textfont /%s findfont %d scalefont def\n",
- opt_encoding ? "OurCharSet" : fontname, fsize - 1);
- fprintf(outfd, "/fnamefont /Times-Bold findfont %d scalefont def\n", HSIZE);
- fprintf(outfd, "/headerfont /Times-Bold findfont %d scalefont def\n",
- HSIZE - 2);
- fprintf(outfd, "textfont setfont\n");
- fprintf(outfd, "(a) stringwidth pop /mp_a_x exch def\n");
- # ifdef DEBUG
- if (Debug_flag & DB_PSMPAGE)
- fprintf(outfd, "(\\t'a' length ) print mp_a_x ==\nflush\n");
- # endif
- fprintf(outfd, "%%%%EndProlog\n");
-
- return;
-
- } /* ps_title */
-
-